#include <stdio.h> 
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>

#include "sm2.h"
#include "key.h"
#include "common_func.h"
#include "core_time.h"

//BSP板级支持包所需全局变量
unsigned long UART_BASE = 0xbf000000;					//UART16550的虚地址
unsigned long CONFREG_TIMER_BASE = 0xbf20f100;			//CONFREG计数器的虚地址
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;		//CONFREG时钟频率
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;			//处理器核时钟频率

int main(int argc, char** argv)
{
	printf("\nHello Loongarch32r SM2 inkey!\n");
	
	//delay_ms(1000);

	uint32_t ret = 0;

	ECCrefPrivateKey prikey = {
		.K = {0x526FF0B7, 0x5DB2D940, 0x89FA76A1, 0x983DB034, 
			  0x0D79FF37, 0xACC58E21, 0x4FAE46A3, 0xC7DAE211}};
	ECCrefPublicKey pubkey = {
		.x = {0x958E4164, 0x204F52F5, 0x4AE34032, 0x23EE5F42, 
		      0xE01ED9EB, 0xECBEE98B, 0x04424CCE, 0x1E7AABD4},
		.y = {0xB3891DE9, 0xBFB2F38F, 0x4F252C38, 0x0590F206, 
			  0xBDA63306, 0x626B646C, 0x76C1D7D9, 0x15D464F5}};
	uint32_t random_k[8] = {
		0x16a25a3d, 0x8e495e9e, 0xfeeb31ce, 0x49e0f38e,   
		0x0d00828e, 0xf8b0c6b4, 0x2b811458, 0x03f0b21f};
	
	uint32_t hash_result[8] = {
		0xc7e8337e, 0xff9f56b1, 0x5ebab182, 0x0051d05f, 
		0x687ed7f4, 0xaaef99cc, 0x3bb277ee, 0xc2101fa2};
	char *pin = "qwer1234";
	ECCSignature signature_result = {0};
	
	printf("prikey.K = ");
	for(int i = 0; i < 8; i++)
	{
		printf("0x%08x ", prikey.K[i]);
	}
	printf("\n");
	printf("pubkey.x = ");
	for(int i = 0; i < 8; i++)
	{
		printf("0x%08x ", pubkey.x[i]);
	}
	printf("\n");
	printf("pubkey.y = ");
	for(int i = 0; i < 8; i++)
	{
		printf("0x%08x ", pubkey.y[i]);
	}
	printf("\n");
	printf("random_k = ");
	for(int i = 0; i < 8; i++)
	{
		printf("0x%08x ", random_k[i]);
	}
	printf("\n");
	printf("hash_result = ");
	for(int i = 0; i < 8; i++)
	{
		printf("0x%08x ", hash_result[i]);
	}
	printf("\n");
	
	ret = write_key(KEY_TYPE_SM2, 0, pin, &prikey, &pubkey, NULL);
	if(ret)
	{
		printf("Write SM2 key faild with ret = 0x%X!\n", ret);
	}
	else
	{
		printf("Write SM2 key success.\n");
	}
	ret = access_key(KEY_TYPE_SM2, 0, pin);
	if(ret)
	{
		printf("Access SM2 key faild with ret = 0x%X!\n", ret);
	}
	else
	{
		printf("Access SM2 key success.\n");
	}
	
	printf("Start test SM2 signature.\n");
	sm2_signature_inkey(random_k, hash_result, &signature_result);
	
	printf("signature_result.r = ");
	for(int i = 0; i < 8; i++)
	{
		printf("0x%08x ", signature_result.r[i]);
	}
	printf("\n");
	printf("signature_result.s = ");
	for(int i = 0; i < 8; i++)
	{
		printf("0x%08x ", signature_result.s[i]);
	}
	printf("\n");
	
	printf("Start test SM2 verify.\n");
	ret = sm2_verify_inkey(&signature_result, hash_result);
	if (ret == 0) {
        printf("SM2 verify success.\n");
    } else {
        printf("SM2 verify Faild with 0x%x.\n", ret);
    }

	release_key(KEY_TYPE_SM2, 0);

	printf("SM2 inkey test finished!\n");
	
	return 0;
}
